package com.gzc.just.play.last.war.sceneserver.move;

import com.gzc.just.play.last.war.sceneserver.gameobject.base.Position;
import com.gzc.just.play.last.war.sceneserver.gameobject.base.Vector3;
import com.gzc.just.play.last.war.sceneserver.gameobject.unit.GameUnit;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 移动管理器 - 管理单位的移动
 *
 * 功能：
 * - 单位的移动和停止
 * - 移向目标点或目标单位
 * - 碰撞检测
 * - 速度修正
 * - 移动事件通知
 *
 * 对应C++的 SSMoveMgr 移动系统
 *
 * @author AI编程助手
 * @version 1.0
 * @since 2025-11-22
 */
public class MoveManager {
    
    private static final Logger log = LoggerFactory.getLogger(MoveManager.class);
    
    // 地图边界
    private static final float MAP_MIN_X = 0.0f;
    private static final float MAP_MAX_X = 2000.0f;
    private static final float MAP_MIN_Z = 0.0f;
    private static final float MAP_MAX_Z = 2000.0f;
    
    private final GameUnit owner;
    private Vector3 moveDirection = Vector3.ZERO;
    private GameUnit targetUnit = null;
    private Position targetPosition = null;
    private boolean isMoving = false;
    private final List<MoveListener> listeners = new CopyOnWriteArrayList<>();
    
    /**
     * 创建移动管理器
     *
     * @param owner 移动对象的所有者
     */
    public MoveManager(GameUnit owner) {
        this.owner = owner;
    }
    
    /**
     * 开始朝指定方向移动
     *
     * @param direction 移动方向（应该是单位向量）
     * @param speed 移动速度
     */
    public void moveInDirection(Vector3 direction, float speed) {
        if (direction == null || speed <= 0) {
            stopMove();
            return;
        }
        
        // 检查是否被控制
        if (isControlled()) {
            log.debug("单位被控制，无法移动");
            return;
        }
        
        // 规范化方向
        Vector3 normalizedDir = direction.normalize();
        this.moveDirection = normalizedDir.multiply(speed);
        this.targetUnit = null;
        this.targetPosition = null;
        this.isMoving = true;
        
        log.debug("开始移动，方向: {}, 速度: {}", direction, speed);
        notifyMoveStarted();
    }
    
    /**
     * 移向目标位置
     *
     * @param target 目标位置
     * @param speed 移动速度
     */
    public void moveToPosition(Position target, float speed) {
        if (target == null || speed <= 0) {
            stopMove();
            return;
        }
        
        if (isControlled()) {
            log.debug("单位被控制，无法移动");
            return;
        }
        
        Position currentPos = owner.getPosition();
        if (currentPos == null) {
            return;
        }
        
        // 计算方向
        double dx = target.getX() - currentPos.getX();
        double dz = target.getZ() - currentPos.getZ();
        double distance = Math.sqrt(dx * dx + dz * dz);
        
        if (distance < 0.1) {
            // 已到达目标
            stopMove();
            return;
        }
        
        // 创建移动方向
        Vector3 direction = new Vector3((float)(dx / distance), 0, (float)(dz / distance));
        this.moveDirection = direction.multiply((float)speed);
        this.targetPosition = target;
        this.targetUnit = null;
        this.isMoving = true;
        
        log.debug("开始移向位置: {} 速度: {}", target, speed);
        notifyMoveStarted();
    }
    
    /**
     * 移向目标单位
     *
     * @param target 目标单位
     * @param distance 与目标保持的距离
     * @param speed 移动速度
     */
    public void moveToUnit(GameUnit target, float distance, float speed) {
        if (target == null || speed <= 0) {
            stopMove();
            return;
        }
        
        if (isControlled()) {
            log.debug("单位被控制，无法移动");
            return;
        }
        
        this.targetUnit = target;
        this.targetPosition = null;
        this.isMoving = true;
        
        // 立即移动
        updateMovement(0);
        
        log.debug("开始移向单位: {} 距离: {} 速度: {}", target.getObjectId(), distance, speed);
    }
    
    /**
     * 停止移动
     */
    public void stopMove() {
        if (!isMoving) {
            return;
        }
        
        this.isMoving = false;
        this.moveDirection = Vector3.ZERO;
        this.targetUnit = null;
        this.targetPosition = null;
        
        log.debug("停止移动");
        notifyMoveStopped();
    }
    
    /**
     * 更新单位移动
     *
     * @param deltaTime 距离上次更新的时间间隔（毫秒）
     */
    public void updateMovement(long deltaTime) {
        if (!isMoving) {
            return;
        }
        
        // 检查是否被控制
        if (isControlled()) {
            stopMove();
            return;
        }
        
        Position currentPos = owner.getPosition();
        if (currentPos == null) {
            return;
        }
        
        // 如果有目标单位，更新移动方向
        if (targetUnit != null) {
            Position targetPos = targetUnit.getPosition();
            if (targetPos != null) {
                moveToPosition(targetPos, (float) moveDirection.length());
            }
        }
        
        // 如果有目标位置，检查是否到达
        if (targetPosition != null) {
            double dist = currentPos.distance(targetPosition);
            if (dist < 1.0) {
                stopMove();
                return;
            }
        }
        
        // 计算移动距离
        double deltaSeconds = deltaTime / 1000.0;
        Vector3 movement = moveDirection.multiply((float)deltaSeconds);
        
        // 计算新位置
        double newX = currentPos.getX() + movement.getX();
        double newZ = currentPos.getZ() + movement.getZ();
        
        // 边界检查
        newX = Math.max(MAP_MIN_X, Math.min(MAP_MAX_X, newX));
        newZ = Math.max(MAP_MIN_Z, Math.min(MAP_MAX_Z, newZ));
        
        // 更新位置
        Position newPos = new Position((float) newX, currentPos.getY(), (float) newZ);
        owner.setPosition(newPos);
        
        notifyMoveUpdated(newPos);
    }
    
    /**
     * 检查单位是否被控制（不能移动）
     */
    private boolean isControlled() {
        // 这里应该检查单位是否有控制类状态效果
        // 如眩晕、冻结、禁锢等
        return false;
    }
    
    /**
     * 检查是否在移动
     */
    public boolean isMoving() {
        return isMoving;
    }
    
    /**
     * 获取当前移动速度
     */
    public double getSpeed() {
        return moveDirection.length();
    }
    
    /**
     * 获取当前移动方向
     */
    public Vector3 getDirection() {
        if (moveDirection.length() <= 0) {
            return Vector3.ZERO;
        }
        return moveDirection.normalize();
    }
    
    /**
     * 获取目标位置
     */
    public Position getTargetPosition() {
        return targetPosition;
    }
    
    /**
     * 获取目标单位
     */
    public GameUnit getTargetUnit() {
        return targetUnit;
    }
    
    /**
     * 添加移动事件监听器
     */
    public void addListener(MoveListener listener) {
        if (listener != null) {
            listeners.add(listener);
        }
    }
    
    /**
     * 移除移动事件监听器
     */
    public void removeListener(MoveListener listener) {
        listeners.remove(listener);
    }
    
    /**
     * 通知移动开始
     */
    private void notifyMoveStarted() {
        for (MoveListener listener : listeners) {
            try {
                listener.onMoveStarted(owner, moveDirection);
            } catch (Exception e) {
                log.error("移动开始监听器异常", e);
            }
        }
    }
    
    /**
     * 通知移动停止
     */
    private void notifyMoveStopped() {
        for (MoveListener listener : listeners) {
            try {
                listener.onMoveStopped(owner);
            } catch (Exception e) {
                log.error("移动停止监听器异常", e);
            }
        }
    }
    
    /**
     * 通知移动更新
     */
    private void notifyMoveUpdated(Position newPosition) {
        for (MoveListener listener : listeners) {
            try {
                listener.onPositionChanged(owner, newPosition);
            } catch (Exception e) {
                log.error("位置变化监听器异常", e);
            }
        }
    }
    
    /**
     * 获取移动摘要
     */
    public String getMoveSummary() {
        if (!isMoving) {
            return "未移动";
        }
        
        return String.format("移动中 - 速度: %.1f, 方向: %s",
            getSpeed(), getDirection());
    }
}
